package com.parkingspace.util;

import io.jsonwebtoken.*;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * ClassName: JwtUtils
 * Package: com.gzp.util
 *
 * @author: guanzepeng
 * @Date: 2021/4/25 23:12 星期日
 * @Description:
 */
public class JwtUtils {
	/**
	 * 私钥密码,保存在服务器,客户端是不会知道密码的,以防止被攻击
	 */
	private static final String SECRET = "mysecret";

	/**
	 * 加密方式
	 */
	private static final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

	/**
	 * 对密钥进行加密
	 *
	 * @return
	 */
	private static Key getkey() {
		byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
		return new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
	}

	/**
	 * 生成Token
	 * <p>
	 * JWT分成3部分：1.头部（header)，2.载荷，3.签证（signature)
	 * <p>
	 * 加密后这3部分密文的字符位数为：
	 * 1.头部（header)：36位，Base64编码
	 * 2.载荷（payload)：没准，BASE64编码
	 * 3.签证（signature)：43位，将header和payload拼接生成一个字符串，
	 * 使用HS256算法和我们提供的密钥（secret,服务器自己提供的一个字符串），
	 * 对str进行加密生成最终的JWT
	 *
	 * @return
	 * @throws Exception
	 */
	public static String createToken(String username, int expireSeconds) {

		// 组合header
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("alg", "HS256");
		map.put("typ", "JWT");
		JwtBuilder builder = Jwts.builder();
		builder.setHeaderParams(map);

		// 有效载荷，存放了用户名
		builder.claim("username", username);


		// 生成第三部分
		builder.signWith(SignatureAlgorithm.HS256, getkey());

		// 签发时间
		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);

		// 设置过期时间
		if (expireSeconds >= 0) {
			long expMillis = nowMillis + (expireSeconds + 2) * 1000;
			Date expDate = new Date(expMillis);
			builder.setExpiration(expDate); // 过期时间
		}
		builder.setIssuedAt(now);

		String token = builder.compact();
		return token;
	}

	/**
	 * 解密Token查看其是否合法
	 *
	 * @param token
	 * @return
	 */
	public static boolean verifyToken(String token) {
		Claims body = null;
		try {
			body = Jwts.parser().setSigningKey(getkey()).parseClaimsJws(token).getBody();
		} catch (SignatureException e) {
			e.printStackTrace();
		} catch (ExpiredJwtException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return body != null;
	}

	public static String getUsername(String token) {
		Claims body = null;
		try {
			body = Jwts.parser().setSigningKey(getkey()).parseClaimsJws(token).getBody();
		} catch (Exception e) {
			return null;
		}
		return (String) body.get("username");   // 该测试这里了
	}
}
